package com.gzyj.jtt808.v2013.protocol;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.annotation.JSONField;
import com.gzyj.jtt808.common.GPSPosition;
import com.gzyj.jtt808.utils.HexBytesUtil;
import com.gzyj.jtt808.v2011.additionalinfo.*;
import com.gzyj.jtt808.v2011.protocol.subiao.*;
import com.gzyj.jtt808.v2013.enums.BusinessDataType;
import com.gzyj.jtt808.v2013.model.position.GnssDataBasicInfo;
import com.gzyj.jtt808.v2013.Package;
import com.gzyj.jtt808.v2013.model.position.additionalInfo.*;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import lombok.Data;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author lhj
 */
@Data
public class JTT808_0x0200 extends Package implements Serializable {

    private GnssDataBasicInfo gnssDataBasicInfo;//位置基本信息
    private List<JTT808_AddtionalInfo> gnssDataAdditionalInfo;//位置附加项列表

    public JTT808_0x0200() {
        super(BusinessDataType.位置信息汇报.getCode());

        this.map = new HashMap<>();
        this.map.put(0x01, JTT808_0x0200_0x01.class.getName());
        this.map.put(0x02, JTT808_0x0200_0x02.class.getName());
        this.map.put(0x03, JTT808_0x0200_0x03.class.getName());
        this.map.put(0x04, JTT808_0x0200_0x04.class.getName());
        this.map.put(0x11, JTT808_0x0200_0x11.class.getName());
        this.map.put(0x12, JTT808_0x0200_0x12.class.getName());
        this.map.put(0x13, JTT808_0x0200_0x13.class.getName());
        this.map.put(0x14, JTT808_0x0200_0x14.class.getName());
        this.map.put(0x15, JTT808_0x0200_0x15.class.getName());
        this.map.put(0x16, JTT808_0x0200_0x16.class.getName());
        this.map.put(0x17, JTT808_0x0200_0x17.class.getName());
        this.map.put(0x18, JTT808_0x0200_0x18.class.getName());

        this.map.put(0x25, JTT808_0x0200_0x25.class.getName());
        this.map.put(0x2A, JTT808_0x0200_0x2A.class.getName());
        this.map.put(0x2B, JTT808_0x0200_0x2B.class.getName());
        this.map.put(0x30, JTT808_0x0200_0x30.class.getName());
        this.map.put(0x31, JTT808_0x0200_0x31.class.getName());

        this.map.put(0x64, JTT808_0x0200_0x64.class.getName());
        this.map.put(0x65, JTT808_0x0200_0x65.class.getName());
        this.map.put(0x66, JTT808_0x0200_0x66.class.getName());
        this.map.put(0x67, JTT808_0x0200_0x67.class.getName());
        this.map.put(0x70, JTT808_0x0200_0x70.class.getName());

        this.map.put(0x6A, JTT808_0x0200_0x6A.class.getName());
    }

    @JSONField(serialize = false)
    private Map<Integer, String> map;

    public int datalen() {
        int len = gnssDataBasicInfo.datalen();

        for (JTT808_AddtionalInfo info : gnssDataAdditionalInfo) {
            int d = 2 + info.getLength();
            len += d;
        }
        return len;
    }

    public void encodeImpl(ByteBuf buf) {
        this.gnssDataBasicInfo.encode(buf);

        if (CollectionUtil.isNotEmpty(this.gnssDataAdditionalInfo)) {
            for (JTT808_AddtionalInfo info : gnssDataAdditionalInfo) {
                info.encode(buf);
            }
        }


    }

    public JTT808_0x0200 decodeImpl(ByteBuf buf) {
        String hex = ByteBufUtil.hexDump(buf);
        this.gnssDataBasicInfo = new GnssDataBasicInfo();
        gnssDataBasicInfo.decode(buf);

        if (buf.readableBytes() > 0) {
            this.gnssDataAdditionalInfo = new ArrayList<>();

        } else {
            return this;
        }

        byte[] t = HexBytesUtil.readByOffset(buf, buf.readableBytes());
        ByteBuf in = Unpooled.copiedBuffer(t);

        if (this.gnssDataAdditionalInfo != null) {

            while (in.readableBytes() > 0) {
//                byte[] temp = HexBytesUtil.readByOffset(in, 1);

                int id = in.readByte();

                try {
                    if (this.map.get(id) != null) {
                        JTT808_AddtionalInfo addtionalInfo = (JTT808_AddtionalInfo) Class.forName(this.map.get(id)).newInstance();
                        addtionalInfo.decode(in);
                        this.gnssDataAdditionalInfo.add(addtionalInfo);
                    } else {
                        int len = in.readByte();
                        if (len > 0) {
                            if (len < in.readableBytes()) {
                                HexBytesUtil.readByOffset(in, len);
                            } else {
                                HexBytesUtil.readByOffset(in, in.readableBytes());
                            }

                        }
                    }


                } catch (Exception e) {
                    System.out.println("位置解析错误 " + hex);
                }


            }

        }


        return this;
    }





    public GPSPosition transform(){
        JTT808_0x0200 jtt808_0x0200=this;
        GPSPosition gpsPosition=new GPSPosition(){{
            version="2013";
            msgId=jtt808_0x0200.getPackageHeader().getMsgId();
            alarmFlagVal=jtt808_0x0200.getGnssDataBasicInfo().getAlarmFlagVal();
            STATUSBIT=jtt808_0x0200.getGnssDataBasicInfo().getSTATUSBIT();
            LAT=Long.valueOf(Integer.parseUnsignedInt(String.valueOf(jtt808_0x0200.getGnssDataBasicInfo().getLAT())));
            LNG=Long.valueOf(Integer.parseUnsignedInt(String.valueOf(jtt808_0x0200.getGnssDataBasicInfo().getLNG())));
            ALTITUDE=Integer.valueOf(jtt808_0x0200.getGnssDataBasicInfo().getALTITUDE());
            SPEED=Integer.valueOf(jtt808_0x0200.getGnssDataBasicInfo().getSPEED());
            DIRECTION=Integer.valueOf(jtt808_0x0200.getGnssDataBasicInfo().getDIRECTION());
            TIME=jtt808_0x0200.getGnssDataBasicInfo().getTIME();
            gnssDataAdditionalInfo=jtt808_0x0200.getGnssDataAdditionalInfo();
            terminalPhoneNo=jtt808_0x0200.getPackageHeader().getTerminalPhoneNo();

        }};
        return gpsPosition;
    }

}
